    //
//  CorAnimation.m
//  AnimationStudy
//
//  Created by longhuihu on 11-6-24.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "CorAnimationController.h"
#import <QuartzCore/QuartzCore.h>

CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
CGFloat RadiansToDegrees(CGFloat radians) {return radians * 180 / M_PI;};

@interface CorAnimationBase : UIControl
{
	NSArray *imageArray;
	NSInteger imageIndex;
	CALayer* faceLayer;
	CALayer* sceneLayer;
}
- (IBAction)actionStartAnimation:(id)sender;
- (void)startAnimation;
@end

@implementation CorAnimationBase

-(id)initWithFrame:(CGRect)frame
{
	if (self=[super initWithFrame:frame]) {
		[self addTarget:self action:@selector(actionStartAnimation:) forControlEvents:UIControlEventTouchUpInside];
		
		imageArray = [NSArray arrayWithObjects:[UIImage imageNamed:@"scene1.jpg"],
					  [UIImage imageNamed:@"scene2.jpg"],
					  [UIImage imageNamed:@"scene3.jpg"],
					  [UIImage imageNamed:@"scene4.jpg"],
					  [UIImage imageNamed:@"scene5.jpg"],nil];
		[imageArray retain];
		
		imageIndex = 0;
		
		faceLayer = [[CALayer alloc] init] ;
		faceLayer.frame = CGRectMake(10, 10, 50, 50);
		faceLayer.contents= (id)[[UIImage imageNamed:@"face.png"] CGImage];
		
		sceneLayer = [[CALayer alloc] init] ;
		sceneLayer.frame = CGRectMake(5, 5,self.bounds.size.width-10, self.bounds.size.height-10);
		sceneLayer.contents = (id)[(UIImage*)[imageArray objectAtIndex:imageIndex] CGImage];
	}
	return self;
}

-(void)drawRect:(CGRect)rect
{
	CGContextRef context = UIGraphicsGetCurrentContext();
	const CGFloat color[] = {1,1,1,1.0};
	const CGFloat linieColor[] = {0,0.5,1,1.0};
	CGContextSetFillColor(context, color);
	CGContextSetStrokeColor(context, linieColor);
	CGContextSetLineWidth(context, 2);
	CGContextFillRect(context, self.bounds);
	CGContextStrokeRect(context, CGRectMake(1, 1, self.bounds.size.width-2, self.bounds.size.height-2));
}

-(void)actionStartAnimation:(id)sender
{
	[self startAnimation];
}
- (void)startAnimation
{
}
@end

@interface ImplicitLayerAnimation : CorAnimationBase
@end
@implementation ImplicitLayerAnimation
-(id)initWithFrame:(CGRect)frame
{
	if (self=[super initWithFrame:frame]) {
		[self.layer addSublayer:sceneLayer];
		[self.layer addSublayer:faceLayer];
		sceneLayer.transform = CATransform3DMakeScale(-1,1,1);
		CGPoint center = sceneLayer.anchorPoint;
		NSLog(@"%f,%f",center.x,center.y);
	}
	return self;
}
- (void)startAnimation
{
	//sceneLayer.hidden = !sceneLayer.hidden;
	
	//sceneLayer.transform = CATransform3DMakeRotation(DegreesToRadians(180),0,0,1);
	
	imageIndex += 1;
	imageIndex %= [imageArray count];
	sceneLayer.contents = (id)[(UIImage*)[imageArray objectAtIndex:imageIndex] CGImage];
}
@end

@interface BasicLayerAnimation : CorAnimationBase
@end
@implementation BasicLayerAnimation
-(id)initWithFrame:(CGRect)frame
{
	if (self=[super initWithFrame:frame]) {
		[self.layer addSublayer:sceneLayer];
		[self.layer addSublayer:faceLayer];
	}
	return self;
}
- (void)startAnimation
{
	CABasicAnimation *theAnimation;
	
	theAnimation=[CABasicAnimation animationWithKeyPath:@"opacity"];
	theAnimation.duration=1.0;
	//theAnimation.repeatCount=0;
	//theAnimation.autoreverses=NO; //autoreverses的行为和UIView Animation的语义basic不同
	theAnimation.fromValue=[NSNumber numberWithFloat:1.0];
	theAnimation.toValue=[NSNumber numberWithFloat:0.0];
	[sceneLayer addAnimation:theAnimation forKey:@"animateOpacity"];
}
@end

/**
 通过delegate改变默认的动画效果,注意：layer的delegate不能是其所在view本身
 */
@interface MyCALayerDelegate : NSObject
@end

@implementation MyCALayerDelegate
- (id<CAAction>)actionForLayer:(CALayer *)theLayer forKey:(NSString *)theKey
{
	
    CATransition *theAnimation=nil;
	
    if ([theKey isEqualToString:@"contents"])
    {
		
        theAnimation = [[[CATransition alloc] init] autorelease];
        theAnimation.duration = 0.5;
        theAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
        theAnimation.type = kCATransitionMoveIn;
        theAnimation.subtype = kCATransitionFromRight;
    }
	
    return theAnimation;
	
	//返回 NSNull可以disable掉这个key相关的动画
	//return [NSNull null];  
}
@end


@interface ActionAnimation : CorAnimationBase
@end
@implementation ActionAnimation
-(id)initWithFrame:(CGRect)frame
{
	if (self=[super initWithFrame:frame]) {
		[self.layer addSublayer:sceneLayer];
		[self.layer addSublayer:faceLayer];
		
		sceneLayer.delegate = [[MyCALayerDelegate alloc] init];
		
		self.clipsToBounds = YES;
	}
	return self;
}
- (void)startAnimation
{
	imageIndex += 1;
	imageIndex %= [imageArray count];
	sceneLayer.contents = (id)[(UIImage*)[imageArray objectAtIndex:imageIndex] CGImage];
}
@end


@interface TransactionAnimation : CorAnimationBase
@end
@implementation TransactionAnimation
-(id)initWithFrame:(CGRect)frame
{
	if (self=[super initWithFrame:frame]) {
		[self.layer addSublayer:sceneLayer];
		[self.layer addSublayer:faceLayer];
	}
	return self;
}
- (void)startAnimation
{
	[CATransaction begin];

//暂时disable动画
//	[CATransaction setValue:(id)kCFBooleanTrue
//					 forKey:kCATransactionDisableActions];
	
	//改变默认动画时间
	[CATransaction setValue:[NSNumber numberWithFloat:2.0f]
					 forKey:kCATransactionAnimationDuration];
	imageIndex += 1;
	imageIndex %= [imageArray count];
	sceneLayer.contents = (id)[(UIImage*)[imageArray objectAtIndex:imageIndex] CGImage];
	
	[CATransaction commit];
}
@end


@interface KeyFrameAnimation : CorAnimationBase
@end
@implementation KeyFrameAnimation
-(id)initWithFrame:(CGRect)frame
{
	if (self=[super initWithFrame:frame]) {
		[self.layer addSublayer:sceneLayer];
		[self.layer addSublayer:faceLayer];
	}
	return self;
}
- (void)startAnimation
{
	/**
	 设置faceLayer的目标值，disable默认的动画
	 */
	[CATransaction begin];
	[CATransaction setValue:(id)kCFBooleanTrue
					 forKey:kCATransactionDisableActions];
	faceLayer.position = CGPointMake(100, 100);
	[CATransaction commit];
	
	CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
	animation.duration = 2.0;
	
	/**
	 using path
	 */
	CGMutablePathRef path = CGPathCreateMutable();
	CGPathMoveToPoint(path, nil, 30, 30);
	CGPathAddLineToPoint(path, nil, 30, 100);
	CGPathAddLineToPoint(path, nil, 100, 100);
	animation.path = path;
	
	/**
	  or using key values to make the same effects
	 */
//	animation.values = [NSArray arrayWithObjects: [NSValue valueWithCGPoint:CGPointMake(30, 30)],
//												   [NSValue valueWithCGPoint:CGPointMake(30, 100)],
//												   [NSValue valueWithCGPoint:CGPointMake(100, 100)],nil];
//	animation.keyTimes = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],
//						  [NSNumber numberWithFloat:0.7],
//						  [NSNumber numberWithFloat:1.0],nil];
	
	[faceLayer addAnimation:animation forKey:@"keyframeAnimation"];
}
@end



@implementation CorAnimationController

// The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization.
    }
    return self;
}
*/

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/

//
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
	
	ImplicitLayerAnimation *implicit = [[ImplicitLayerAnimation alloc] initWithFrame:CGRectMake(0, 0, 130, 130)];
	[self.view addSubview:implicit];
	[implicit release];
	
	BasicLayerAnimation *basic = [[BasicLayerAnimation alloc] initWithFrame:CGRectMake(140, 0, 130, 130)];
	[self.view addSubview:basic];
	[basic release];
	
	ActionAnimation *action = [[ActionAnimation alloc] initWithFrame:CGRectMake(0, 140, 130, 130)];
	[self.view addSubview:action];
	[action release];
	
	TransactionAnimation *transaction = [[TransactionAnimation alloc] initWithFrame:CGRectMake(140, 140, 130, 130)];
	[self.view addSubview:transaction];
	[transaction release];
	
	KeyFrameAnimation *key = [[KeyFrameAnimation alloc] initWithFrame:CGRectMake(0, 280, 130, 130)];
	[self.view addSubview:key];
	[key release];
}


/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations.
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc. that aren't in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
}


@end
